#!/usr/bin/env python3
"""
分析 setuptools.build_meta 的结构和执行流程
Analyze setuptools.build_meta structure and execution flow
"""

import inspect
import setuptools.build_meta as build_meta

def analyze_build_meta():
    """分析 build_meta 模块的结构"""
    print("setuptools.build_meta 模块分析")
    print("=" * 50)
    print(f"模块位置: {build_meta.__file__}")
    print(f"模块文档: {build_meta.__doc__}")
    print()

    # 获取所有公共方法和类
    public_members = [name for name in dir(build_meta) if not name.startswith('_')]
    
    print("公共接口 (PEP 517 钩子函数):")
    print("-" * 30)
    for name in sorted(public_members):
        obj = getattr(build_meta, name)
        if callable(obj):
            try:
                sig = inspect.signature(obj)
                print(f"  {name}{sig}")
                if obj.__doc__:
                    print(f"    说明: {obj.__doc__.strip().split('.')[0]}")
            except ValueError:
                print(f"  {name} (无法获取签名)")
        else:
            print(f"  {name} = {obj}")
    print()

def show_pep517_hooks():
    """显示 PEP 517 标准钩子"""
    print("PEP 517 标准钩子函数:")
    print("-" * 30)
    
    hooks = [
        ("build_wheel", "构建 wheel 文件"),
        ("build_sdist", "构建源码分发包"), 
        ("get_requires_for_build_wheel", "获取构建 wheel 的依赖"),
        ("get_requires_for_build_sdist", "获取构建 sdist 的依赖"),
        ("prepare_metadata_for_build_wheel", "准备 wheel 元数据"),
        ("build_editable", "构建可编辑安装的 wheel"),
        ("get_requires_for_build_editable", "获取可编辑安装的依赖")
    ]
    
    for hook_name, description in hooks:
        if hasattr(build_meta, hook_name):
            print(f"  ✅ {hook_name}: {description}")
        else:
            print(f"  ❌ {hook_name}: {description} (未实现)")
    print()

def show_execution_flow():
    """显示执行流程"""
    print("setuptools.build_meta 执行流程:")
    print("-" * 40)
    print("""
    1. pip 调用 _in_process.py
       ↓
    2. _in_process.py 导入 setuptools.build_meta
       ↓  
    3. 根据命令调用相应的钩子函数:
       - build_editable() ← 你的情况 (pip install -e)
       - build_wheel() 
       - build_sdist()
       ↓
    4. build_meta 内部流程:
       ┌─→ _build_with_temp_dir()
       │   ├─→ run_setup() 
       │   │   └─→ exec(setup.py 代码)
       │   └─→ 处理构建输出
       └─→ 返回构建结果路径
       ↓
    5. pip 获取构建结果并安装
    """)

def show_internal_classes():
    """显示内部类结构"""
    print("内部类和重要组件:")
    print("-" * 25)
    
    # 查找类
    for name in dir(build_meta):
        obj = getattr(build_meta, name)
        if inspect.isclass(obj):
            print(f"  类: {name}")
            # 显示类的方法
            methods = [m for m in dir(obj) if not m.startswith('_') and callable(getattr(obj, m))]
            for method in methods[:3]:  # 只显示前3个方法
                print(f"    - {method}()")
            if len(methods) > 3:
                print(f"    - ... 还有 {len(methods)-3} 个方法")
        elif name.isupper():  # 常量
            print(f"  常量: {name} = {obj}")

def show_your_case():
    """展示你的具体情况"""
    print("你的构建过程分析:")
    print("-" * 25)
    print("""
    pip install -e . -v 触发的调用链:
    
    1. pip 读取 pyproject.toml
       build-backend = "setuptools.build_meta"
       
    2. pip 创建临时构建环境
       安装: setuptools>=64, wheel, cmake>=3.12, pybind11>=2.6.0
       
    3. pip 调用: _in_process.py build_editable
       
    4. _in_process.py 调用: setuptools.build_meta.build_editable()
       
    5. build_editable() 内部:
       ├─→ _build_with_temp_dir()
       ├─→ run_setup() 
       │   └─→ exec(你的 setup.py 代码)
       │       └─→ 调用你的 CMakeBuild.build_extension()
       └─→ 生成可编辑安装的 wheel
       
    6. pip 安装生成的 wheel 到用户环境
    """)

if __name__ == "__main__":
    analyze_build_meta()
    show_pep517_hooks()
    show_internal_classes()
    show_execution_flow()
    show_your_case() 